package ru.dveriwell.intra.finplan.ui;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.servlet.ServletContext;

import org.springframework.context.ApplicationContext;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.ldap.userdetails.InetOrgPerson;
import org.springframework.web.context.support.WebApplicationContextUtils;

import ru.dveriwell.intra.util.DataBindingException;

import com.vaadin.Application;
import com.vaadin.terminal.gwt.server.WebApplicationContext;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.Label;
import com.vaadin.ui.PasswordField;
import com.vaadin.ui.TabSheet;
import com.vaadin.ui.TextField;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;

@SuppressWarnings("serial")
public class FinplanApplication extends Application {

	public EntityManagerFactory emf  = null;
	public EntityManager entityManager = null;
	public static final String JTA_PU_NAME = "finplan";
	
	
	private ApplicationContext context;
	private AuthenticationManager authenticationManager;
	
	private void initDataService() {
		
	    emf = Persistence.createEntityManagerFactory(JTA_PU_NAME);
	    entityManager = emf.createEntityManager();
	    
	}
	
	private void buildMainWindow () {

		removeWindow(getMainWindow());
		Window mainWindow = new Window("Финансовое планирование");
		
//		Select userComboBox = new Select();
//		userComboBox.setCaption("Пользователь");
//		userComboBox.setImmediate(true);
//		TypedQuery<Planuser> getUsersQuery = entityManager.createQuery("select puser from Planuser puser order by puser.username", Planuser.class);
//		BeanContainer<Integer, Planuser> planUsers = new BeanContainer<Integer, Planuser>(Planuser.class);
//		planUsers.setBeanIdProperty("id");
//		planUsers.addAll(getUsersQuery.getResultList());
//		userComboBox.setItemCaptionPropertyId("username");
//		userComboBox.setContainerDataSource(planUsers);
		
		Label userLabel = new Label(((InetOrgPerson)SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getDisplayName());
		userLabel.setCaption("Пользователь");
		
		RequesterTabComposition requesterTab = new RequesterTabComposition();

		
		AdminTabComposition adminTab = new AdminTabComposition();

		
        VerticalLayout l2 = new VerticalLayout();
        l2.setMargin(true);
        l2.addComponent(new Label("В разработке."));

        VerticalLayout l3 = new VerticalLayout();
        l3.setMargin(true);
        l3.addComponent(new Label("В разработке."));

        TabSheet t = new TabSheet();
        t.setHeight("100%");
        t.setWidth("100%");

        t.addTab(requesterTab, "Заявки");
        t.addTab(l2, "БДР");
        t.addTab(l3, "Фин. план");
        t.addTab(adminTab, "Администрирование");
        
        mainWindow.addComponent(t);
        mainWindow.addComponent(userLabel);
        
		try {
			
			requesterTab.bindData(entityManager);
			adminTab.bindData(entityManager);
			
		} catch (DataBindingException e) {
			
			mainWindow.showNotification("Ошибка",
		            "Ошибка загрузки данных",
		            Window.Notification.TYPE_ERROR_MESSAGE);
			e.printStackTrace();
			
		} finally {
        
//			mainWindow.getContent().setSizeFull();
			setMainWindow(mainWindow);
			
		}

	}
	
	public void buildLoginWindow() {
		
		removeWindow(getMainWindow());
		Window mainWindow = new Window("Вход в систему");
		
		VerticalLayout loginLayout = new VerticalLayout();
		
		final TextField loginField = new TextField();
		loginField.setCaption("Имя пользователя");

		final PasswordField passField = new PasswordField();
		passField.setCaption("Пароль");
		
		Button loginBtn  = new Button();
		loginBtn.setCaption("Вход");
		
		loginBtn.addListener(new ClickListener() {
			
			@Override
			public void buttonClick(ClickEvent event) {
				authenticate(loginField.getValue().toString(), passField.getValue().toString());
				
			}
		});

		loginLayout.addComponent(loginField);
		loginLayout.addComponent(passField);
		loginLayout.addComponent(loginBtn);
		
		mainWindow.addComponent(loginLayout);
		mainWindow.getContent().setSizeFull();
		
		setMainWindow(mainWindow);
		
	}
	
	public Authentication authenticate(String username, String password) {
		
		UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(
				username, password);
		Authentication auth = authenticationManager.authenticate(token); 
		if (null != auth) {
			SecurityContextHolder.getContext().setAuthentication(auth);
			
			init();

			return auth;
		}
		throw new BadCredentialsException("null authentication");
	}

	@Override
	public void init() {
		
		if (null == context) {
			ServletContext servletContext = ((WebApplicationContext) this
					.getContext()).getHttpSession().getServletContext();
			context = WebApplicationContextUtils
					.getRequiredWebApplicationContext(servletContext);
		}

		if (null == authenticationManager) {
			authenticationManager = (AuthenticationManager) context
					.getBean("authenticationManager");
		}

		if (SecurityContextHolder.getContext().getAuthentication().getName().equals("anonymousUser")) {
			buildLoginWindow();
		} else {
			System.out.println("Principal login: " + SecurityContextHolder.getContext().getAuthentication().getPrincipal());
//			System.out.println("getCn(): " + ((InetOrgPerson)SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getCn());
//			System.out.println("getDisplayName(): " + ((InetOrgPerson)SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getDisplayName());
			initDataService();
			buildMainWindow();
		}
		
	}
	
}
